/**
 * 
 */
package org.ChrisRiffle.Acme.AcmeTraverser.ActionPerformers;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import org.ChrisRiffle.Acme.AcmeTraverser.AbstractActionPerformer;

/**
 * 
 * Counts the lines of code(LOC) in the encountered java src files
 * 
 * @author RIF
 *
 */
public class JavaSrcLineCounterActionPerfomer extends AbstractActionPerformer {

	
	private static final String OUTPUT_FILENAME = "JavaSrcLineCounterActionPerfomer_Output.csv";
	
	/**
	 * Keys are the file Paths
	 * Values are Integers representing LinesOfCode(in the file)
	 */
	private Map<String,Integer> filePathToLineCountMap = new HashMap<String, Integer>();
	
	int totalLocAllFiles = 0;
	int numFilesProcessed = 0;
	int avgLocPerFile = 0;
	
	/**
	 * Counts lines of code and saves to the output file
	 * 
	 * @see org.ChrisRiffle.Acme.AcmeTraverser.ActionPerformer#doAction(java.io.File)
	 */
	@Override
	public void doAction(File pFile) {

		if (pFile == null 
				|| pFile.isDirectory() 
				|| !pFile.isFile() 
				|| !pFile.exists()
				|| pFile.getName() == null
				|| !pFile.getName().toLowerCase().endsWith(".java")) {

			//ignore, it's not a java src file
			return;
		}	
		
		try {
			
			int fileLinesOfCode = getLineCount(pFile);
			filePathToLineCountMap.put(pFile.getPath(), fileLinesOfCode);
			
			totalLocAllFiles += fileLinesOfCode;
			numFilesProcessed ++;
			
		} catch (IOException e) {

			e.printStackTrace();
		}

	}

	
	/**
	 * Gets the # of lines in the specified file
	 * 
	 * @param pFile
	 *            File to count the lines of
	 * @return
	 * @throws IOException
	 */
	private int getLineCount(File pFile) throws IOException {

		LineNumberReader ln = new LineNumberReader(new FileReader(pFile));

		int lineCount = 0;

		while (ln.readLine() != null) {

			lineCount++;
		}

		return lineCount;
	}
	
	
	/**
	 * @see org.ChrisRiffle.Acme.AcmeTraverser.ActionPerformer#getOutputFileName()
	 */
	@Override
	public String getOutputFileName() {

		return OUTPUT_FILENAME;
	}

	
	
	/**
	 * @throws IOException 
	 * @see org.ChrisRiffle.Acme.AcmeTraverser.ActionPerformer#shutDown()
	 */
	@Override
	public void shutDown() {

		
		try {
			writeOutputFile();
			
			getBufferedWriter().close();
			
			Logger.getAnonymousLogger().info("Wrote results to: "
					+ getOutputFile().getPath());
			
		} catch (IOException e) {

			e.printStackTrace();
			
			Logger.getAnonymousLogger().severe("FAILED writing results");
		}

	}
	
	/**
	 * @throws IOException
	 * 
	 */
	private void writeOutputFile() throws IOException {

		if(filePathToLineCountMap.keySet().size() == 0){
			
			String zeroMsg = "Zero java src files encountered(0 LOC)";
			getBufferedWriter().write(zeroMsg);
			Logger.getAnonymousLogger().info(zeroMsg);
			return;
		}
		
		int avgLocPerFile = totalLocAllFiles / numFilesProcessed;
		
		Logger.getAnonymousLogger().info("File Count = " + numFilesProcessed
				+ ", Avg. LOC per File = " + avgLocPerFile);

		
		for (String iFilePath : filePathToLineCountMap.keySet()) {

			getBufferedWriter().write(
					iFilePath + "," + filePathToLineCountMap.get(iFilePath));

			getBufferedWriter().newLine();
		}
	}

}


